package
{
	import Graphics.Animation;
	
	import Utils.Camera;
	
	import flash.display.BitmapData;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.*;
	
	public class GameSprite extends GameObject
	{
		protected var velocity:Point = new Point(0,0);
		protected var maxVelocity:Point = new Point(0,0);
		protected var acceleration:Point = new Point(0,0);
		protected var maxHealth:Number;
		protected var currentHealth:Number;
		
		protected var isDead:Boolean = false;
		protected var isAttacking:Boolean = false;
		protected var canAttack:Boolean = true;
		protected var attackDelay:int = 20;
		protected var timer:int = 0;
		
		// 0 - UP, 1 - Right, 2 - Down , 3 - Left
		protected var direction:Array = new Array(0,1,2,3);
		protected var currentDirection:int = 0;
		
		
		//animation stuff
		protected var animations:Array;
		protected var currentAnimation:Animation;
		protected var frameTimer:int;
		protected var currentFrame:int;
		protected var finished:Boolean;
		
		//intervals
		private var canInterval:uint;
		private var attackInterval:uint;
		
		
		public function GameSprite(game:Level)
		{
			super(game);
			animations = new Array();
		}
		
		public function Initialize():void
		{
			animations = new Array();
		}
		
		public override function Update(deltaTime:int):void
		{
			super.Update(deltaTime);
			Animate(deltaTime);
		}
		
		private function Animate(deltaTime:int):void
		{
			if((currentAnimation != null) &&(currentAnimation.FrameTime > 0) &&(currentAnimation.Loop || !finished))
			{
				frameTimer += deltaTime;
				while(frameTimer > currentAnimation.FrameTime)
				{
					frameTimer = frameTimer - currentAnimation.FrameTime;
					if(currentFrame == currentAnimation.FrameNumber)
					{
						if(currentAnimation.Loop)
							currentFrame = 0;
						else
							finished = true;
					}
					else
					{
						currentFrame ++;
					}
					blitRectangle.x = currentFrame * width;
					blitRectangle.y = currentDirection * height;
				}
			}
		}
		
		public function PlayAnimation(animationName:String):void
		{
			if(currentAnimation != null)
			{
				if(animationName == currentAnimation.Name && !finished){return;}
				for(var index:int = 0; index < animations.length; index ++)
				{
					if(animations[index].Name == animationName)
					{
						currentAnimation = animations[index];
						finished = false;
						currentFrame = 0;
					}
				}
			}
		}
		
		public override function Draw(camera:Camera, canvas:BitmapData):BitmapData
		{
			this.position.x = this.worldPosition.x - camera.X;
			this.position.y = this.worldPosition.y - camera.Y;
			if(currentAnimation != null)
			{
				if(currentAnimation.Graphic != null && !isDead)
				{
					canvas.copyPixels(currentAnimation.Graphic.bitmapData, blitRectangle, position);
				}
			}
			return canvas;
		}
		
		public function TakeDamage(damage:int):void
		{
			this.currentHealth -= damage;
			if(this.currentHealth < 0)
			{
				this.currentHealth = 0;
				isDead = true;
			}
		}
		
		public function Heal(amount:int):void
		{
			this.currentHealth += amount;
			if(this.currentHealth > maxHealth)
			{
				currentHealth = maxHealth;
			}
		}
		
		public function IncreaseMaxHealth(bonus:int):void
		{
			this.maxHealth += bonus;
		}
		
		public function Attack():void
		{
			if(!isAttacking)isAttacking = true;
			attackInterval = setInterval(AttackDelay, 300);
			if(canAttack)canAttack = false;
			canInterval = setInterval(CanAttack, 1000);
		}
		
		public function AttackDelay():void
		{
			isAttacking = false;
			clearInterval(attackInterval);
		}
		
		public function CanAttack():void
		{
			canAttack = true;
			clearInterval(canInterval);
		}
		
		public override function hitWall():Boolean { velocity.x = 0; return true;}
		public override function hitCeiling():Boolean { velocity.y = 0; return true;}
		public override function hitFloor():Boolean { velocity.y = 0; super.hitFloor(); return true;}
		public function get Velocity():Point { return maxVelocity;}
		public function set IsDead(value:Boolean):void{ isDead = value;}
		public function get IsDead():Boolean{ return isDead;}
		public function get IsAttacking():Boolean{ return isAttacking;}
		public function get Health():int { return currentHealth;}
		public function get MaxHealth():int { return maxHealth;}
		public function get CurrentDirection():int { return currentDirection;}
		
	}
}